package com.zz.admin.testDataTypesManagement.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zz.admin.testDataTypesManagement.dto.TestDataTypesDto;
import com.zz.admin.testDataTypesManagement.entity.TestDataTypes;
import com.zz.admin.testDataTypesManagement.mapper.TestDataTypesMapper;
import com.zz.admin.testDataTypesManagement.service.TestDataTypesService;
import com.zz.common.base.dto.PageListResultDto;
import com.zz.common.base.enums.BaseExceptionEnum;
import com.zz.common.base.param.QueryParam;
import com.zz.common.constants.BaseConstant;
import com.zz.common.exception.ExceptionFactory;
import com.zz.common.utils.common.UUIDGenerator;
import com.zz.common.utils.mapper.BeanMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 数据类型示例 服务实现类
 *
 * @author zl
 * @since 2025-11-23 14:28:32
 */
@Service
@Slf4j
public class TestDataTypesServiceImpl extends ServiceImpl<TestDataTypesMapper, TestDataTypes> implements TestDataTypesService {

    @Resource
    private TestDataTypesMapper testDataTypesMapper;

    @Override
    public PageListResultDto<TestDataTypesDto> queryWithPage(TestDataTypesDto testDataTypesDto, QueryParam queryParam) {
        Page<TestDataTypes> page = new Page<>(queryParam.getPageNum(), queryParam.getPageSize());
        QueryWrapper<TestDataTypes> wrapper = new QueryWrapper<>();
        wrapper.eq("del_flag", BaseConstant.NO);
        if (StringUtils.isNotBlank(testDataTypesDto.getUsername())) {
            wrapper.like("username", "%" + testDataTypesDto.getUsername() + "%");
        }
        if (StringUtils.isNotBlank(testDataTypesDto.getGender())) {
            wrapper.eq("gender", testDataTypesDto.getGender());
        }
        if (StringUtils.isNotBlank(testDataTypesDto.getDescription())) {
            wrapper.eq("description", testDataTypesDto.getDescription());
        }
        if (ObjectUtil.isNotEmpty(testDataTypesDto.getBirthDate())) {
            wrapper.eq("birth_date", testDataTypesDto.getBirthDate());
        }
        if (ObjectUtil.isNotEmpty(testDataTypesDto.getCreatedDatetime())) {
            wrapper.eq("created_datetime", testDataTypesDto.getCreatedDatetime());
        }
        if (ObjectUtil.isNotEmpty(testDataTypesDto.getLoginTime())) {
            wrapper.eq("login_time", testDataTypesDto.getLoginTime());
        }
        if (ObjectUtil.isNotEmpty(testDataTypesDto.getUpdatedAt())) {
            wrapper.eq("updated_at", testDataTypesDto.getUpdatedAt());
        }
        if (ObjectUtil.isNotEmpty(testDataTypesDto.getAge())) {
            wrapper.eq("age", testDataTypesDto.getAge());
        }
        if (ObjectUtil.isNotEmpty(testDataTypesDto.getTotalViews())) {
            wrapper.eq("total_views", testDataTypesDto.getTotalViews());
        }
        if (ObjectUtil.isNotEmpty(testDataTypesDto.getHeight())) {
            wrapper.eq("height", testDataTypesDto.getHeight());
        }
        if (ObjectUtil.isNotEmpty(testDataTypesDto.getWeight())) {
            wrapper.eq("weight", testDataTypesDto.getWeight());
        }
        if (ObjectUtil.isNotEmpty(testDataTypesDto.getSalary())) {
            wrapper.eq("salary", testDataTypesDto.getSalary());
        }
        if (StringUtils.isNotBlank(testDataTypesDto.getLocaleValueStr())) {
            // todo: 具体查询路径根据业务进行修改
            wrapper.apply("JSON_SEARCH(locale_value, 'one', {0}, NULL, '$')",
                        testDataTypesDto.getLocaleValueStr());
        }
        page = testDataTypesMapper.selectPage(page, wrapper);
        List<TestDataTypes> testDataTypess = testDataTypesMapper.selectList(page, wrapper);
        List<TestDataTypesDto> testDataTypesDtos = BeanMapper.mapList(testDataTypess, TestDataTypes.class, TestDataTypesDto.class);
        return new PageListResultDto<>((int) page.getCurrent(), (int) page.getTotal(), queryParam.getPageSize(), testDataTypesDtos);
    }

    @Override
    public List<TestDataTypesDto> queryWithNoPage(TestDataTypesDto testDataTypesDto) {
        QueryWrapper<TestDataTypes> wrapper = new QueryWrapper<>();
        wrapper.eq("del_flag", BaseConstant.NO);
        List<TestDataTypes> testDataTypess = testDataTypesMapper.selectList(wrapper);
        return BeanMapper.mapList(testDataTypess, TestDataTypes.class, TestDataTypesDto.class);
    }

    @Override
    public TestDataTypesDto queryById(String id) {
        if (StringUtils.isBlank(id)) {
            return null;
        }
        TestDataTypes testDataTypes = testDataTypesMapper.selectById(id);
        if (testDataTypes == null || BaseConstant.YES.equals(testDataTypes.getDelFlag())) {
            return null;
        }
        TestDataTypesDto dto = BeanMapper.map(testDataTypes, TestDataTypesDto.class);
        return dto;
    }


    @Override
    public List<TestDataTypesDto> queryByIds(List<String> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return new ArrayList<>();
        }
        List<TestDataTypes> testDataTypess = testDataTypesMapper.selectByIds(ids);
        if (CollectionUtils.isEmpty(testDataTypess)) {
            return new ArrayList<>();
        }
        List<TestDataTypesDto> dtos = BeanMapper.mapList(testDataTypess, TestDataTypes.class, TestDataTypesDto.class);
        return dtos;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public TestDataTypesDto save(TestDataTypesDto testDataTypesDto) {
        TestDataTypesDto result = insert(testDataTypesDto);
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<TestDataTypesDto> saveBatch(List<TestDataTypesDto> testDataTypesDtos) {
        List<TestDataTypesDto> results = insertList(testDataTypesDtos);
        return results;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public TestDataTypesDto modify(TestDataTypesDto testDataTypesDto) {
        updateById(testDataTypesDto);
        return testDataTypesDto;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<TestDataTypesDto> modifyBatch(List<TestDataTypesDto> testDataTypesDtos) {
        List<TestDataTypesDto> results = updateList(testDataTypesDtos);
        return results;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int trueDelete(String id) {
        TestDataTypes entity = new TestDataTypes();
        entity.setId(id);
        return testDataTypesMapper.deleteById(id);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(String id) {
        // 根据业务修改
        TestDataTypesDto testDataTypesDto = new TestDataTypesDto();
        testDataTypesDto.setId(id);
        deleteById(testDataTypesDto);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteBatch(List<String> ids) {
        // 根据业务修改
        deleteByIds(ids);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public TestDataTypesDto insert(TestDataTypesDto testDataTypesDto) {
        testDataTypesDto.setId(UUIDGenerator.generateUUID());
        testDataTypesDto.setDelFlag(BaseConstant.NO);
        TestDataTypes entity = BeanMapper.map(testDataTypesDto, TestDataTypes. class);
        testDataTypesMapper.insert(entity);
        return testDataTypesDto;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public TestDataTypesDto insertWithId(TestDataTypesDto testDataTypesDto) {
        if (StringUtils.isBlank(testDataTypesDto.getId())) {
            testDataTypesDto.setId(UUIDGenerator.generateUUID());
        }
        testDataTypesDto.setDelFlag(BaseConstant.NO);
        TestDataTypes entity = BeanMapper.map(testDataTypesDto, TestDataTypes.class);
        testDataTypesMapper.insert(entity);
        return testDataTypesDto;
    }

    private List<TestDataTypesDto> insertList(List<TestDataTypesDto> testDataTypesDtos) {
        if (CollectionUtils.isEmpty(testDataTypesDtos)) {
            throw ExceptionFactory.createBaseException(BaseExceptionEnum.NOT_FOUND, "批量插入时，参数不能为空");
        }
        List<TestDataTypes> insertList = new ArrayList<>();
        for (TestDataTypesDto testDataTypesDto : testDataTypesDtos) {
            if (StringUtils.isBlank(testDataTypesDto.getId())) {
                testDataTypesDto.setId(UUIDGenerator.generateUUID());
            }
            testDataTypesDto.setDelFlag(BaseConstant.NO);
            insertList.add(BeanMapper.map(testDataTypesDto, TestDataTypes.class));
        }
        testDataTypesMapper.insert(insertList, 1000);
        return testDataTypesDtos;
    }

    private List<TestDataTypesDto> updateList(List<TestDataTypesDto> testDataTypesDtos) {
        if (CollectionUtils.isEmpty(testDataTypesDtos)) {
            throw ExceptionFactory.createBaseException(BaseExceptionEnum.NOT_FOUND, "批量更新时，参数不能为空");
        }
        for (TestDataTypesDto testDataTypesDto : testDataTypesDtos) {
            if (StringUtils.isBlank(testDataTypesDto.getId())) {
                throw ExceptionFactory.createBaseException(BaseExceptionEnum.NOT_FOUND, "批量更新时，主键不能为空");
            }
        }
        List<TestDataTypes> testDataTypesList = BeanMapper.mapList(testDataTypesDtos, TestDataTypesDto.class, TestDataTypes.class);
        testDataTypesMapper.updateById(testDataTypesList, 1000);
        return testDataTypesDtos;
    }

    @Transactional(rollbackFor = Exception.class)
    public int updateById(TestDataTypesDto testDataTypesDto) {
        if (StringUtils.isBlank(testDataTypesDto.getId())) {
            throw ExceptionFactory.createBaseException(BaseExceptionEnum.INTERNAL_SERVER_ERROR, "更新时，主键不能为空");
        }
        TestDataTypes entity = BeanMapper.map(testDataTypesDto, TestDataTypes.class);
        return testDataTypesMapper.updateById(entity);
    }

    @Transactional(rollbackFor = Exception.class)
    public int deleteById(TestDataTypesDto testDataTypesDto) {
        testDataTypesDto.setDelFlag(BaseConstant.YES);
        return updateById(testDataTypesDto);
    }
    
    @Transactional(rollbackFor = Exception.class)
    public void deleteByIds(List<String> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            throw ExceptionFactory.createBaseException(BaseExceptionEnum.NOT_FOUND, "批量删除时，参数不能为空");
        }
        for (String id : ids) {
            TestDataTypesDto testDataTypesDto = new TestDataTypesDto();
            testDataTypesDto.setId(id);
            testDataTypesDto.setDelFlag(BaseConstant.YES);
            updateById(testDataTypesDto);
        }
    }

}
